package com.linkgie.galaxyframework.binaryserialize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.linkgie.galaxyframework.utils.TextEncoding;

/**
 * 标记一个接口的字段作为二进制类型({@link BinaryType})的字段；
 * <p>
 * 
 * 字段的数据类型需要需要显式通过
 * {@link #primitiveType()}、{@link #isEnum()}、{@link #isObject()}
 * 3个属性之一标注（只能标记一种）；
 * 
 * @author huanghaiquan
 *
 */
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface BinaryField {

	/**
	 * 字段索引；
	 * <p>
	 * 字段索引是表示字段唯一性的编号，同时也是字段在二进制序列中的排序序号；
	 * <p>
	 * 在序列化时，字段索引并不会输出到实际的二进制序列，仅用于对字段进行升序排列；
	 * <p>
	 * 
	 * 注：对于已经发布使用的数据契约，都不应该调整顺序，否则会导致无法正确解析已有数据；
	 * 
	 * @return
	 */
	int index();

	/**
	 * 字段的基本数据类型；
	 * <p>
	 * 
	 * 如果字段的类型属于 {@link PrimitiveType} 枚举中的基本数据类型，则需要显式指定一种具体的类型；
	 * 
	 * @return
	 */
	PrimitiveType primitiveType() default PrimitiveType.NIL;

	/**
	 * 数值编码；
	 * <p>
	 * 字段为基本类型 {@link #primitiveType()} 的文本({@link PrimitiveType#TEXT}) 时，此设置才生效；
	 * 
	 * @return
	 */
	TextEncoding textEncoding() default TextEncoding.CHARSET_UTF8;

	/**
	 * 数值编码；
	 * <p>
	 * 字段为基本类型 {@link #primitiveType()} 的整数(INT8 ~ INT64) 时，此设置才生效；
	 * 
	 * @return
	 */
	NumberEncoding numberEncoding() default NumberEncoding.NONE;

	/**
	 * 字段是否为枚举类型；
	 * <p>
	 * 如果为 true，则属性的声明类型必须是枚举类型，且该枚举类型已经标记 {@link BinaryEnum}； enumerable
	 * 
	 * @return
	 */
	boolean isEnum() default false;

	/**
	 * 字段类型是嵌套的二进制对象类型；
	 * <p>
	 * 
	 * 如果为 true，则属性的声明类型必须是接口类型，且该类型已经标记了 {@link BinaryType};
	 * 
	 * @return
	 */
	boolean isObject() default false;

	/**
	 * 字段声明的类型是否是抽象类型；
	 * <p>
	 * 如果为 true ，字段嵌套的二进制类型是否根据实际的对象实现的二进制接口动态写入；
	 * <p>
	 * 仅当 {@link #isObject()} 为 true 时，此属性的设置才有效；
	 * 
	 * @return
	 */
	boolean isAbstract() default false;

	/**
	 * 是否可迭代的多项列表；
	 * 
	 * @return
	 */
	boolean iterable() default false;

	/**
	 * 最大长度，单位为“byte”
	 * <p>
	 * 仅对于文本、字节数组、大整数等相关的数据类型有效（即：{@link PrimitiveType} 枚举中编码大于等于 0x20
	 * {@link PrimitiveType#TEXT}的数据类型）；
	 * 
	 * @return
	 */
	int maxSize() default -1;

	/**
	 * 名称；
	 * <p>
	 * 默认为属性的名称；
	 * 
	 * @return
	 */
	String name() default "";

	/**
	 * 关于字段的说明；
	 * <p>
	 * 
	 * 说明内容将输出到数据段的数据结构描述文件；
	 * 
	 * @return
	 */
	String decription() default "";

}
